package code.lucamarrocco.rest;

import java.util.*;

public class RestfulProtocol {

	public RestfulProtocol example(String url)
	{
		method.addExample(url);
		return this;
	}
	
	public RestfulProtocol namespace(String namespace) {
		this.namespace = namespace;
		return this;
	}

	public RestfulProtocol goal(String name) {
		return resource(name);
	}

	public RestfulProtocol version(String version) {
		this.version = version;
		return this;
	}

	public RestfulProtocol accomplish(String description) {
		method.setDescription(description);
		return this;
	}

	public RestfulProtocol are(String description) {
		return this;
	}

	public RestfulProtocol auth(String name) {
		auth = name;
		method.auth(auth);
		return this;
	}

	public RestfulProtocol authenticated() {
		return this;
	}

	public RestfulProtocol DELETE(String pattern) {
		method = RestfulMethod.DELETE(topic.getName(), resource.getName(), formatless(namespaceless(pattern)));
		methods.add(method);
		resource.add(method);
		return this;
	}

	public RestfulProtocol GET(String pattern) {
		method = RestfulMethod.GET(topic.getName(), resource.getName(), formatless(namespaceless(pattern)));
		methods.add(method);
		resource.add(method);
		return this;
	}

	public RestfulProtocol is(String description) {
		method.parameter(parameter, description, requiredOrOptional);
		return this;
	}

	public RestfulProtocol note(String note) {
		method.addNote(note);
		return this;
	}

	public RestfulProtocol optional() {
		requiredOrOptional = false;
		return this;
	}

	public RestfulProtocol or() {
		return this;
	}

	public RestfulProtocol parameter(String name) {
		parameter = name;
		method.parameter(parameter, null, requiredOrOptional);
		return this;
	}
	
	public String namespaceless(String pattern)
	{
		return pattern.replaceAll(namespace, "");
	}

	public String formatless(String pattern)
	{
		return pattern.replaceAll(".\\{format\\}$", "");
	}

	public RestfulProtocol POST(String pattern) {
		method = RestfulMethod.POST(topic.getName(), resource.getName(), formatless(namespaceless(pattern)));
		methods.add(method);
		resource.add(method);
		return this;
	}

	public RestfulProtocol PUT(String pattern) {
		method = RestfulMethod.PUT(topic.getName(), resource.getName(), formatless(namespaceless(pattern)));
		methods.add(method);
		resource.add(method);
		return this;
	}

	public RestfulProtocol require() {
		requiredOrOptional = true;
		return this;
	}

	public RestfulProtocol resource(String name) {
		resource = new RestfulResource(name);
		topic.addResource(resource);
		resources.add(resource);
		return this;
	}

	public RestfulProtocol that() {
		return this;
	}

	public RestfulProtocol that(String description) {
		method.parameter(parameter, description, requiredOrOptional);
		return this;
	}

	public RestfulProtocol topic(String name) {
		topic = new RestfulTopic(name);
		topics.add(topic);
		return this;
	}
	
	protected String namespace = "";

	public String getNamespace() {
		return namespace;
	}

	public String getVersion() {
		return namespace.replaceAll("^.*/", "");
	}

	public String getName() {
		String name = namespace;
		name = name.replaceAll("http://", "");
		name = name.replaceAll("api.", "");
		name = name.replaceAll(".com", "");
		name = name.replaceAll("/.*$", "");
		return name;
	}

	protected String version;

	protected List<RestfulResource> resources = new LinkedList<RestfulResource>();

	protected List<RestfulTopic> topics = new LinkedList<RestfulTopic>();

	protected List<RestfulMethod> methods = new LinkedList<RestfulMethod>();

	protected RestfulMethod method;

	protected RestfulResource resource;

	protected String parameter;

	protected RestfulTopic topic = new RestfulTopic("Default");

	protected String auth;

	public List<RestfulMethod> getMethods() {
		return methods;
	}

	public List<RestfulResource> getResources() {
		return resources;
	}

	public List<RestfulTopic> getTopics() {
		return topics;
	}

	protected boolean requiredOrOptional = false;

	public void setRequiredOrOptional(boolean requiredOrOptional) {
		this.requiredOrOptional = requiredOrOptional;
	}
}